#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QProcess>
#include <QTimer>
#include <QMap>
#include <QSemaphore>
#include <QThread>
#include <QSerialPort>
#include <QUdpSocket>
#include <QHostAddress>
#include <QLabel>
#include <QPushButton>
#include <QScrollBar>
#include <QHash>
#include <QtCharts>
#include <QMap>
#include <QVector>
#include <QGraphicsTextItem>

#include "pcanreceiver.h"
#include "CanAscLogger.h"
#include "sendcanprotmanager.h"
#include "serialmanager.h"
#include "customvideostream.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    bool testPcanConnection();

    //初始化 QLabel标签 为圆形，灰色
    void setLabelLightStyle();
    void resetWidget(QTabWidget *widget);

    //清除 Iperf3 响应的数据
    void Iperf3_ClearClicked(const int &index, const QString &dataTableWidget0, const QString &btArgc0, const QString &badTextEdit0);

    //启动 暂停 Iperf3 进程
    void Iperf3_StartorPause_Process(const QString &id, const int &index, const QString &btStart0,const QString &textBad0, const QString &CmdArgs0);

    //根据正则表达式 解析 Iperf3 应答的数据
    void parseIperf3Data(const QString &output, const QString &id, const int &index,const QString &dTabWidget,const QString &lostPack,const QString &totalPack, const QString &lostRate,const QString &labellossC,const QString &passButton);

    //展示更新应答的数据
    //void updateDataIperf3(const int &index,const QString &dTabWidget,const QString &lostPack,const QString &totalPack, const QString &lostRate,const QString &labellossC,const QString &passButton);

    //发送 BVCU_115 信号设置
    void sendPCANBVCU_115(QMap<QString, QVariant> &signalValues);

    //发送 CPU_51 信号设置
    void sendPCANCPU_51(QMap<QString, QVariant> &signalValues);

    //PCAN 数据接收 设置配置界面
    void setPCANConfigUI(const QString& sigName, double physValue);

    //PCAN 数据接收 设置系统状态界面
    void setPCANSystemStatus(const QString& sigName, double physValue);

    //设置PCAN 信号灯颜色
    void setLightColorsStyle(QWidget *widget1, const QString& sigName, double physValue);

    //PCAN 数据接收 设置通信及控制界面
    void setPCANComControl(const quint32 &msgId,const QString& sigName, double physValue);

    //PCAN 数据接收 设置电源诊断界面
    void setPCANPowerCheck(const quint32 &msgId,const QString& sigName, double physValue);

    //初始化温度曲线
    void inintemperatureCurve();
    void updatePWMValue();
    void setCurrTemperatCurve(const QString& sigName, double physValue);

    // 初始化串口管理器
    void initSerialManagers();

    // 从界面获取串口配置
    bool getSerialConfig(const int &index, const QString &serialPort, QString &portName, qint32 &baudRate,
                        QSerialPort::DataBits &dataBits,
                        QSerialPort::Parity &parity,
                        QSerialPort::StopBits &stopBits);

    // 发送数据到指定串口
    void sendToPort(const QString &portKey);

    // 更新按钮状态
    void updateButtonState(const QString &portKey, const QString &statusInfo);

    //UDP消息发送并接收消息
    bool sendUdpMessage();
    // 视频播放初始化
    void initVideoPlayer();
    // 设置视频流信号槽连接
    void setupVideoConnections();
    // 简化的状态消息显示
    void showStatusMessage(const QString &message);
    // 停止视频流
    void stopVideoStream();

private slots:

    //截图
    void on_savePixMap_clicked();

    //接收解析 iperf3 输出
    void onIperf3OutputReady(const QString &id,const int &index,const QString &dTabWidget,const QString &lostPack,const QString &totalPack, const QString &lostRate,const QString &labellossC,const QString &passButton);
    //统一的错误处理槽函数
    void onIperf3ErrorOccurred(const QString &id, const int &index, const QString &errorMsg);
    // 进程结束处理
    void onProcessFinished(const QString &id, const int &index, int exitCode, QProcess::ExitStatus exitStatus);

    //310P-1 千兆1界面启动 清除
    void on_P1_1_Start_clicked();
    void on_P1_1_Clear_clicked();

    void on_P1_2_Start_clicked();
    void on_P1_2_Clear_clicked();

    void on_P2_1_Start_clicked();
    void on_P2_1_Clear_clicked();

    void on_P2_2_Start_clicked();
    void on_P2_2_Clear_clicked();

    void on_D2000_1_Start_clicked();
    void on_D2000_1_Clear_clicked();

    void on_D2000_2_Start_clicked();
    void on_D2000_2_Clear_clicked();

    void on_Computer_1_Start_clicked();
    void on_Computer_1_Clear_clicked();

    void on_Computer_2_Start_clicked();
    void on_Computer_2_Clear_clicked();

    void on_Computer_3_Start_clicked();
    void on_Computer_3_Clear_clicked();

    void on_Computer_4_Start_clicked();
    void on_Computer_4_Clear_clicked();

    //展示更新应答的数据
    void updateDataIperf3(const int &index,const QString &dTabWidget,const QString &lostPack,const QString &totalPack, const QString &lostRate,const QString &labellossC,const QString &passButton);


    //启动PCAN设备
    void on_PCAN_Start_clicked();

    //设置保存文件路径
    void on_saveFilePushButton_clicked();

    //PCAN接收数据 错误信息
    void onErrorOccurred(const QString& errorMsg);

    //查看设备是否连接
    void onConnectionStatusChanged(bool isConnected);

    //PCAN接收 解析完后的数据
    void onSignalReceived(const QString& msgName, quint32 msgId, const QByteArray& data,
                             const QString& sigName, double physValue, const QString& valueDesc);
    //定时发送数据的槽函数
    void onSendCanMessages();

    //关闭PCAN设备
    void on_PCAN_Close_clicked();

    //PCAN 数据发送控制
//    void on_Control_Start_clicked();

    //串口通信发送
    void on_serialPort_Send_clicked();
    void onSerialSendTimeout();
    // 处理接收到的数据
    void handleDataReceived(const QString &portName, const QByteArray &data);
    // 处理端口状态变化
    void handlePortStatusChanged(const QString &portName, const QString &statusInfo);

    void on_MCU_232_openSerialPort_activated(int index);

    void on_RS485_openSerialPort_activated(int index);

    void on_RS422_openSerialPort_activated(int index);

    void on_GPRMC_openSerialPort_activated(int index);

    void on_serialPort_Clear_clicked();

    //相机开始按钮
    void on_camera_start_clicked();

    //接收UDP服务端返回数据
    void onReadyReadUdp();

    void updateFrame(const QImage &frame);
    void onFrameRateUpdated(double fps);
    // 处理视频初始化结果
    void onVideoInitialized(bool isReady);
    // 处理视频连接失败 - 简化提示
    void onVideoConnectionFailed();

    void on_RS485_2_openSerialPort_activated(int index);

private:
    Ui::MainWindow *ui;
    QMutex runningMapMutex;

    bool HLPower = false;
    bool HLPowerFlag = true;
    QTimer *sendTimer;  // 定时发送定时器 100ms
    QTimer *HLOutTimer;  // 高边输出控制 1s
    SendCANProtManager* m_canProtManager; // CAN报文管理器
    PCANReceiver *pcanReceiver; //接收数据
    CanAscLogger *canLogger;  // PCAN日志记录
    bool PCANlog = false;
    QString ascPath;
    double SendNum = 0;          // 发送数据总数量
    double SendFD_Success = 0;   // 发送数据成功数量
    double ReciveNum = 0;          // 接收数据总数量
    double ReciveFD_Success = 0;   // 接收数据成功数量
    // 发送 存储报文名称与上一帧时间戳的映射
    QMap<QString, qint64> lastTimestampMap;

    // 1. 存储每个msgId的上一次接收时间戳（单位：毫秒）
    QHash<quint32, qint64> lastMsgIdReceiveTime;
    // 2. 存储每个msgId的超时次数计数器（超过1秒接收间隔则+1，未超过保持不变）
    QHash<quint32, int> msgIdTimeoutCount;
    // 3. 超时阈值：1秒 = 1000毫秒
    const qint64 MSGID_TIMEOUT_THRESHOLD = 1000;

    QChart *temperaturePlot;
    QMap<QString, QLineSeries*> seriesMap;
    // 存储各温度信号的时间和值数据
    QMap<QString, QVector<double>> timeDataMap;
    QMap<QString, QVector<double>> valueDataMap;
    // 用于生成时间戳（可根据实际系统时间调整）
    qint64 startTime;
    QGraphicsTextItem *pwmInfoItem = nullptr;

    // 用于管理 iperf3 进程
    QMap<QString, QProcess*> iperf3ProcessMap;
    // 并发控制（限制最大进程数）
    QSemaphore concurrentSemaphore;
    // 状态管理（避免直接使用全局isRunning）
    QMap<QString, bool> processRunningMap;

    bool isRunning = false; // 测试状态标记
    QString interval;      // 时间间隔
    QString transfer;      // 传输量
    QString bandwidth;     // 带宽
    QString timeStamp;     // 时间戳
    int lostPackets;       // 丢包数
    int totalPackets;      // 发送总数
    QString lossRate;      // 丢包率（百分比）
    int lossCount;         // 丢包次数

    // 串口管理器映射
    QMap<QString, SerialPortManager*> m_serialPorts;
    QTimer *sendTimerSerial; //串口定时发送
    bool m_isSending;

    CanAscLogger *cameraLogger = nullptr;  // 相机日志记录
    QUdpSocket *m_udpSocket = nullptr;
    QHostAddress m_serverAddress;
    quint16 m_serverPort;
    VideoStream*   video_stream_ = nullptr;
    bool is_playing_ = false;
    QLabel* videoLabel = nullptr;
    QPushButton* startBt = nullptr;


};
#endif // MAINWINDOW_H
